package model;

// 导入ArrayList和List类，用于创建和管理课程列表
import java.util.ArrayList;
import java.util.List;

/**
 * 学生类
 * 继承自Person类，添加选课相关功能
 * 这是一个具体的子类，实现了父类中定义的抽象方法printWorksheet()
 */
public class Student extends Person {
    // 私有属性：存储学生所选的课程列表
    private List<Course> selectedCourses; // 所选课程列表
    
    /**
     * 构造方法
     * @param id 学生编号
     * @param name 学生姓名
     * @param gender 学生性别
     * 使用super()调用父类Person的构造方法来初始化人员基本信息
     * 同时初始化所选课程列表为空的ArrayList
     */
    public Student(String id, String name, String gender) {
        // 调用父类的构造方法，传入学生的基本信息
        super(id, name, gender);
        // 初始化课程列表，准备存储学生选择的课程
        selectedCourses = new ArrayList<>();
    }
    
    /**
     * 选课方法 - 学生选择一门课程
     * @param course 要选择的课程对象
     * 1. 首先检查学生是否已经选过这门课
     * 2. 如果没选过，调用课程的addStudent方法尝试添加学生
     * 3. 如果添加成功，将课程添加到学生的课程列表中
     * 4. 根据结果输出相应的提示信息
     */
    public void selectCourse(Course course) {
        // 步骤1：检查学生是否已经选过这门课程
        if (selectedCourses.contains(course)) {
            // 输出提示：学生已经选过这门课程
            System.out.printf("学生信息：编号=%s，姓名=%s，性别=%s，已经选择过课程《%s》%n",
                    getId(), getName(), getGender(), course.getName());
            // 结束方法执行
            return;
        }
        
        // 步骤2：尝试将学生添加到课程中（这里会检查课程容量）
        if (course.addStudent(this)) {
            // 步骤3：如果添加成功，将课程添加到学生的课程列表
            selectedCourses.add(course);
            // 输出选课成功的提示信息
            System.out.printf("学生信息：编号=%s，姓名=%s，性别=%s，成功选择课程《%s》%n",
                    getId(), getName(), getGender(), course.getName());
        } else {
            // 如果课程已满，输出选课失败的提示信息
            System.out.printf("学生信息：编号=%s，姓名=%s，性别=%s，选择课程《%s》失败，课程已满%n",
                    getId(), getName(), getGender(), course.getName());
        }
    }
    
    /**
     * 退课方法 - 学生退选一门课程
     * @param course 要退选的课程对象
     * 1. 检查学生是否选过这门课
     * 2. 如果选过，从学生的课程列表中移除
     * 3. 同时从课程的学生列表中移除学生
     * 4. 输出相应的提示信息
     */
    public void dropCourse(Course course) {
        // 步骤1：检查学生是否选过这门课程
        if (selectedCourses.contains(course)) {
            // 步骤2：从学生的课程列表中移除这门课
            selectedCourses.remove(course);
            // 步骤3：从课程的学生列表中移除该学生
            course.removeStudent(this);
            // 输出退课成功的提示信息
            System.out.printf("学生信息：编号=%s，姓名=%s，性别=%s，成功退选课程《%s》%n",
                    getId(), getName(), getGender(), course.getName());
        } else {
            // 如果学生没选过这门课，输出无法退课的提示信息
            System.out.printf("学生信息：编号=%s，姓名=%s，性别=%s，未选择过课程《%s》，无法退课%n",
                    getId(), getName(), getGender(), course.getName());
        }
    }
    
    /**
     * 重写父类Person中的抽象方法printWorksheet
     * 实现打印学生课表的功能
     * 1. 打印学生的基本信息
     * 2. 检查学生是否选课
     * 3. 如果选课了，遍历所有课程并打印课程详情
     * 4. 使用三元运算符处理教师可能为空的情况
     */
    @Override // 注解表示这是重写父类的方法
    public void printWorksheet() {
        // 步骤1：打印学生基本信息
        System.out.printf("学生信息：编号=%s，姓名=%s，性别=%s%n",
                getId(), getName(), getGender());
        
        // 步骤2：检查学生是否选择了课程
        if (selectedCourses.isEmpty()) {
            // 如果没有选课，输出相应提示
            System.out.println("该学生目前未选择任何课程");
        } else {
            // 如果有选课，输出课程列表标题
            System.out.println("所选课程列表：");
            // 步骤3：遍历所有已选课程并打印详细信息
            for (Course course : selectedCourses) {
                // 步骤4：使用三元运算符处理教师可能为空的情况
                System.out.printf("  课程编号：%s，课程名称：%s，地点：%s，教师：%s%n",
                        course.getId(), course.getName(), course.getLocation(),
                        course.getTeacher() != null ? course.getTeacher().getName() : "无");
            }
        }
    }
    
    /**
     * 获取学生所选课程的列表
     * @return 学生所选课程的List集合
     * 这是一个getter方法，提供对私有属性的只读访问
     */
    public List<Course> getSelectedCourses() {
        return selectedCourses;
    }
}
